//
//  UITableViewCell+Init.m
//  TableView
//
//  Created by liaozhenming on 16/5/16.
//  Copyright © 2016年 liaozhenming. All rights reserved.
//

#import "UITableViewCell+Init.h"

#import <objc/runtime.h>


@implementation UITableView(Init)

+ (void)load {
    
    Method registerClass = class_getInstanceMethod([self class], NSSelectorFromString(@"registerClass:forCellReuseIdentifier:"));
    Method kk_registerClass = class_getInstanceMethod([self class], @selector(kk_registerClass:forCellWithReuseIdentifier:));
    method_exchangeImplementations(registerClass, kk_registerClass);
    
    Method registerXib = class_getInstanceMethod([self class], NSSelectorFromString(@"registerNib:forCellReuseIdentifier:"));
    Method kk_registerXib = class_getInstanceMethod([self class], @selector(kk_registerNib:forCellWithReuseIdentifier:));
    method_exchangeImplementations(registerXib, kk_registerXib);
}

- (void)kk_registerClass:(nullable Class)cellClass forCellWithReuseIdentifier:(NSString *)identifier {
    
    if (identifier != nil) {
        if (![self kk_hasRegisterIdentifier: identifier]) {
            NSMutableArray *identifiers = [NSMutableArray array];
            [identifiers arrayByAddingObjectsFromArray: self.kk_identifiers];
            [identifiers addObject: identifier];
            [self setKk_identifiers: identifiers];
        }
    }
    
    [self kk_registerClass: cellClass forCellWithReuseIdentifier: identifier];
}

- (void)kk_registerNib:(UINib *)nib forCellWithReuseIdentifier:(NSString *)identifier {
    
    if (identifier != nil) {
        if (![self kk_hasRegisterIdentifier: identifier]) {
            NSMutableArray *identifiers = [NSMutableArray array];
            [identifiers arrayByAddingObjectsFromArray: self.kk_identifiers];
            [identifiers addObject: identifier];
            [self setKk_identifiers: identifiers];
        }
    }
    
    [self kk_registerNib: nib forCellWithReuseIdentifier: identifier];
}

- (BOOL)kk_hasRegisterIdentifier:(NSString*)identifier {
    
    for (NSString *item in self.kk_identifiers) {
        if ([item isEqualToString: identifier]) {
            return YES;
        }
    }
    return NO;
}

@dynamic kk_identifiers;
static const void *UICollectionViewRegisterIdentifiers = &UICollectionViewRegisterIdentifiers;
- (void)setKk_identifiers:(NSMutableArray *)kk_identifiers {
    objc_setAssociatedObject(self, UICollectionViewRegisterIdentifiers, kk_identifiers, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSMutableArray*)kk_identifiers {
    return objc_getAssociatedObject(self, UICollectionViewRegisterIdentifiers);
}

#pragma mark - public methods

- (void)kk_registerCellClassNames:(NSArray*)cellClassNames {
    
    for (NSString *className in cellClassNames) {
        
        NSString *xibPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: [NSString stringWithFormat: @"%@.nib",className]];
        if (![[NSFileManager defaultManager] fileExistsAtPath: xibPath]) {
            [self registerClass: NSClassFromString(className) forCellReuseIdentifier: className];
        }
        else {
            [self registerNib:[UINib nibWithNibName: className bundle: [NSBundle mainBundle]] forCellReuseIdentifier: className];
        }
    }
}

@end

@implementation UITableViewCell (Init)

+ (instancetype)kk_cellWithTableView:(UITableView*)tableView {
    return [self kk_cellWithTableView: tableView identifier: NSStringFromClass(self.class) indexPath: nil];
}

+ (instancetype)kk_cellWithTableView:(UITableView*)tableView indexPath:(NSIndexPath*)indexPath {
    return [self kk_cellWithTableView: tableView identifier: NSStringFromClass(self.class) indexPath: indexPath];
}

+ (instancetype)kk_cellWithTableView:(UITableView *)tableView identifier:(NSString *)identifier {
    return [self kk_cellWithTableView: tableView identifier: identifier indexPath: nil];
}

+ (instancetype)kk_cellWithTableView:(UITableView *)tableView identifier:(NSString *)identifier indexPath:(NSIndexPath*)indexPath {
    
    if (indexPath == nil) {
        //  不带有indexPath的方式
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: identifier];
        if (cell == nil) {
            
            NSString *resoucePath = [[NSBundle mainBundle] resourcePath];
            NSArray *xibPaths = [[NSFileManager defaultManager] contentsOfDirectoryAtPath: resoucePath error: nil];
            if (xibPaths) {
                BOOL hasOwne = NO;
                NSString *fileName = NSStringFromClass(self.class);
                for (NSString *itemPath in xibPaths) {
                    if ([itemPath hasPrefix: fileName]) {
                        hasOwne = YES;
                        break;
                    }
                }
                if (hasOwne) {
                    [tableView registerNib:[UINib nibWithNibName: NSStringFromClass([self class]) bundle: nil] forCellReuseIdentifier: identifier];
                    cell = [tableView dequeueReusableCellWithIdentifier: identifier];
                    return cell;
                }
            }
            cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: identifier];
        }
        return cell;
    }
    else {
        UITableViewCell* cell = nil;
        if (![tableView kk_hasRegisterIdentifier: identifier]) {
            
            NSString *xibPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: [NSString stringWithFormat: @"%@.nib",NSStringFromClass(self.class)]];
            if (![[NSFileManager defaultManager] fileExistsAtPath: xibPath]) {
                [tableView registerClass: self.class forCellReuseIdentifier: identifier];
            }
            else {
                [tableView registerNib: [UINib nibWithNibName: NSStringFromClass(self.class) bundle: [NSBundle mainBundle]] forCellReuseIdentifier: identifier];
            }
        }
        cell = [tableView dequeueReusableCellWithIdentifier: identifier forIndexPath: indexPath];
        return cell;
    }
}

@end
